package com.carleasoft.mps.adu.business.menu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carleasoft.mps.adu.business.menu.bean.entity.AuthorityMenuEntity;
import com.carleasoft.mps.adu.business.menu.service.AuthorityMenuService;
import com.carleasoft.mps.adu.business.role.bean.vo.ListAndButtonVo;
import com.carleasoft.mps.adu.business.role.bean.vo.MenuButtonVo;
import com.carleasoft.mps.adu.business.role.bean.vo.PermVo;
import com.carleasoft.mps.adu.business.menu.dao.AuthorityMenuDao;
import com.carleasoft.mps.adu.common.constants.BusinessErrorEnum;
import com.carleasoft.mps.adu.common.pops.ShiroMenuConfig;
import com.carleasoft.mps.core.exceptions.BusinessException;
import com.carleasoft.mps.core.user.UserCacheData;
import com.carleasoft.mps.core.utils.IBeanUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>Description: role serviceImpl</p>
 *
 * @author ztm
 * @since 2020-05-11
 */
@Service
public class AuthorityMenuServiceImpl extends ServiceImpl<AuthorityMenuDao, AuthorityMenuEntity> implements AuthorityMenuService {


    @Autowired
    ShiroMenuConfig shiroMenuConfig;
    @Autowired
    AuthorityMenuDao authorityMenuDao;



    @Override
    public List<ListAndButtonVo> getListAndButton(List<String> menuNameList) {
        //获取所有菜单和按钮
        QueryWrapper<AuthorityMenuEntity> queryWrapper = new QueryWrapper<AuthorityMenuEntity>();
        queryWrapper.in("NAME", menuNameList);
        List<AuthorityMenuEntity> all = authorityMenuDao.selectList(queryWrapper);
        if (all == null || all.size() <= 0) {
            return null;
        }
        //获取顶层菜单
        List<AuthorityMenuEntity> top = all.stream().filter(a -> {
            return (StringUtils.isEmpty(a.getParentName()) || a.getParentName().equals("")) && a.getMenuType() == 2;
        }).collect(Collectors.toList());
        //拼装子菜单
        List<ListAndButtonVo> returnList = new LinkedList<>();
        if (top != null && top.size() > 0) {
            top.stream().forEach(a -> {
                ListAndButtonVo listAndButtonVo = new ListAndButtonVo();
                List<AuthorityMenuEntity> buttons = all.stream().filter(x -> {
                    return StringUtils.isNotBlank(x.getParentName()) && x.getParentName().equals(a.getName()) && x.getMenuType() == 1;
                }).collect(Collectors.toList());
                BeanUtils.copyProperties(a, listAndButtonVo);
                if (buttons != null && buttons.size() > 0) {
                    List<String> names = buttons.stream().map(AuthorityMenuEntity::getName).collect(Collectors.toList());
                    listAndButtonVo.setButtonList(names);
                }
                returnList.add(listAndButtonVo);
            });
            this.diGuiListAndButton(all, returnList);
        }
        return returnList;
    }

    @Override
    public PermVo getMenuAndButton(List<String> menuNameList) {
        if (menuNameList==null){
            return null;
        }
        //获取所有菜单和按钮
        QueryWrapper<AuthorityMenuEntity> queryWrapper = new QueryWrapper<AuthorityMenuEntity>();
        queryWrapper.in("NAME", menuNameList);
        List<AuthorityMenuEntity> all = authorityMenuDao.selectList(queryWrapper);
        if (all == null || all.size() <= 0) {
            return null;
        }
        // 获取所有非按钮类型菜单
        List<AuthorityMenuEntity> allMenuList = all.stream().filter(a -> {
            return a.getMenuType() == 2;
        }).collect(Collectors.toList());
        // 获取所有按钮
        List<AuthorityMenuEntity> allButtonList = all.stream().filter(a -> {
            return a.getMenuType() == 1;
        }).collect(Collectors.toList());
        PermVo permVo = new PermVo();
        Map<String, List<String>> mbMap = getMenuButtonMap(allMenuList, allButtonList);
        permVo.setMenuButtonMap(mbMap);
        //获取顶层菜单
        List<MenuButtonVo> topMenuList = all.stream().filter(a -> {
            return (StringUtils.isEmpty(a.getParentName()) || a.getParentName().equals("")) && a.getMenuType() == 2;
        }).map(e -> {
            MenuButtonVo tmbv = new MenuButtonVo();
            MenuButtonVo.MetaProps metaProps = new MenuButtonVo.MetaProps();
            BeanUtils.copyProperties(e, metaProps);
            BeanUtils.copyProperties(e, tmbv);
            tmbv.setMeta(metaProps);
            return tmbv;
        }).collect(Collectors.toList());
        List<MenuButtonVo> allMenus = allMenuList.stream().map(e -> {
            MenuButtonVo tmbv = new MenuButtonVo();
            MenuButtonVo.MetaProps metaProps = new MenuButtonVo.MetaProps();
            BeanUtils.copyProperties(e, metaProps);
            BeanUtils.copyProperties(e, tmbv);
            tmbv.setMeta(metaProps);
            return tmbv;
        }).collect(Collectors.toList());
        // 组装菜单树
        for (MenuButtonVo menuButtonVo : topMenuList) {
            buildMenuTree(allMenus, menuButtonVo);
        }
        permVo.setMenuVoList(topMenuList);
        return permVo;
    }

    // 获取所有菜单下的按钮
    private Map<String, List<String>> getMenuButtonMap(List<AuthorityMenuEntity> allMenuList, List<AuthorityMenuEntity> allButtonList) {
        if (allMenuList == null || allButtonList == null || allMenuList.size() == 0 || allButtonList.size() == 0)
            return null;
        Map<String, List<String>> mbMap = new HashMap<String, List<String>>();
        allMenuList.forEach(authorityMenuEntity -> {
            List<AuthorityMenuEntity> filterList = allButtonList.stream().filter(x -> {
                return StringUtils.isNotBlank(x.getParentName()) && x.getParentName().equals(authorityMenuEntity.getName());
            }).collect(Collectors.toList());
            if (filterList.size() > 0) {
                List<String> buttonNameList = filterList.stream().map(AuthorityMenuEntity::getName).collect(Collectors.toList());
                mbMap.put(authorityMenuEntity.getName(), buttonNameList);
            }
        });
        return mbMap;
    }

    // 组装权限菜单树
    private MenuButtonVo buildMenuTree(List<MenuButtonVo> menuList, MenuButtonVo menuTree) {
        List<MenuButtonVo> childrenMenuList = new ArrayList<>();
        for (MenuButtonVo menuButtonVo : menuList) {
            if (StringUtils.isNotEmpty(menuButtonVo.getParentName()) && menuButtonVo.getParentName().equals(menuTree.getName())) {
                childrenMenuList.add(buildMenuTree(menuList, menuButtonVo));
            }
        }
        if (childrenMenuList.size() > 0) {
            menuTree.setChildren(childrenMenuList);
        }
        return menuTree;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addListOrButton(AuthorityMenuEntity authorityMenuEntity, UserCacheData user) {
        // 菜单类型不可重名，需要验证
        LambdaQueryWrapper<AuthorityMenuEntity> queryWrapper = new LambdaQueryWrapper<AuthorityMenuEntity>();
        queryWrapper.eq(AuthorityMenuEntity::getName, authorityMenuEntity.getName());
        AuthorityMenuEntity one = authorityMenuDao.selectOne(queryWrapper);
        if (Objects.nonNull(one)) {
            throw new BusinessException(BusinessErrorEnum.MENU_EXISTS);
        }
        authorityMenuDao.insert(authorityMenuEntity);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean editListOrButton(AuthorityMenuEntity authorityMenuEntity, UserCacheData user) {
        IBeanUtil.paramVerify(authorityMenuEntity, "id");
        authorityMenuDao.updateById(authorityMenuEntity);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteListOrButton(AuthorityMenuEntity authorityMenuEntity, UserCacheData user) {
        IBeanUtil.paramVerify(authorityMenuEntity, "id");

        //校验有没有子集
        AuthorityMenuEntity id = authorityMenuDao.selectOne(new QueryWrapper<AuthorityMenuEntity>().eq("ID", authorityMenuEntity.getId()));
        if (id == null) {
            throw new BusinessException(BusinessErrorEnum.BUTTON_OR_LIST_NO);
        }
        Integer integer = authorityMenuDao.selectCount(new QueryWrapper<AuthorityMenuEntity>().eq("PARENT_NAME", authorityMenuEntity.getName()));
        if (integer > 0) {
            throw new BusinessException(BusinessErrorEnum.BUTTON_OR_LIST_CHILD);
        }
        authorityMenuDao.deleteById(authorityMenuEntity);
        return true;
    }

    /**
     * 递归拼装菜单和按钮
     */
    public List<ListAndButtonVo> diGuiListAndButton(List<AuthorityMenuEntity> all, List<ListAndButtonVo> returnList) {
        returnList.stream().forEach(a -> {
            //获取子菜单
            List<AuthorityMenuEntity> collect = all.stream().filter(b -> {
                return StringUtils.isNotBlank(b.getParentName()) && b.getParentName().equals(a.getName()) && b.getMenuType() == 2;
            }).collect(Collectors.toList());
            //获取子按钮
            List<AuthorityMenuEntity> button = all.stream().filter(b -> {
                return StringUtils.isNotBlank(b.getParentName()) && b.getParentName().equals(a.getName()) && b.getMenuType() == 1;
            }).collect(Collectors.toList());

            List<ListAndButtonVo> child = new LinkedList<>();
            if (collect != null && collect.size() > 0) {
                collect.stream().forEach(c -> {
                    ListAndButtonVo l = new ListAndButtonVo();
                    BeanUtils.copyProperties(c, l);
                    child.add(l);
                });
                a.setChildren(child);
                this.diGuiListAndButton(all, child);
            }
            List<String> buttonList = new LinkedList<>();
            if (button != null && button.size() > 0) {
                button.stream().forEach(c -> {
                    buttonList.add(c.getName());
                });
            }
            a.setButtonList(buttonList);
        });
        return returnList;
    }

    @Override
    public List<ListAndButtonVo> ListAndButtonTree() {
        //获取所有菜单和按钮
        QueryWrapper<AuthorityMenuEntity> queryWrapper = new QueryWrapper<AuthorityMenuEntity>();
        List<AuthorityMenuEntity> all = authorityMenuDao.selectList(queryWrapper);
        if (all == null || all.size() <= 0) {
            return null;
        }
        //获取顶层菜单
        List<AuthorityMenuEntity> top = all.stream().filter(a -> {
            return StringUtils.isEmpty(a.getParentName()) || a.getParentName().equals("");
        }).collect(Collectors.toList());
        //拼装子菜单
        List<ListAndButtonVo> returnList = new LinkedList<>();
        if (top != null && top.size() > 0) {
            top.stream().forEach(a -> {
                ListAndButtonVo listAndButtonVo = new ListAndButtonVo();
                BeanUtils.copyProperties(a, listAndButtonVo);
                returnList.add(listAndButtonVo);
            });
            this.diGui(all, returnList);
        }
        return returnList;
    }

    /**
     * 递归拼装菜单和按钮
     */
    public List<ListAndButtonVo> diGui(List<AuthorityMenuEntity> all, List<ListAndButtonVo> returnList) {
        returnList.stream().forEach(a -> {
            //获取子
            List<AuthorityMenuEntity> collect = all.stream().filter(b -> {
                return StringUtils.isNotBlank(b.getParentName()) && b.getParentName().equals(a.getName());
            }).collect(Collectors.toList());

            List<ListAndButtonVo> child = new LinkedList<>();
            if (collect != null && collect.size() > 0) {
                collect.stream().forEach(c -> {
                    ListAndButtonVo l = new ListAndButtonVo();
                    BeanUtils.copyProperties(c, l);
                    child.add(l);
                });
                a.setChildren(child);
                this.diGui(all, child);
            }
        });
        return returnList;
    }


}

